package org.monkey4j;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;

import org.apache.commons.beanutils.PropertyUtils;
import org.junit.runners.model.Statement;
import org.monkey4j.suppliers.SupplierFactory;

import com.google.common.base.Supplier;

/**
 * Factory for creating statements used within a monkey testing environment.
 * 
 * @author hillger.t
 */
public class StatementFactory {
	private final MonkeyUtil monkeyUtil;
	
	public StatementFactory(Class<?> testClass) {
		monkeyUtil = new MonkeyUtil(testClass);
	}

	public Statement newRepetitiveStatement(Object currentRunningTest, Statement formerTestStatement) {
		for (Field field : monkeyUtil.getMonkeyAnnotatedFields()) {
			try {
				String property = monkeyUtil.getMonkeyPropery((Field) field);
				Object bean = field.get(currentRunningTest);

				Class<?> propertyType = PropertyUtils.getPropertyDescriptor(bean, property).getPropertyType();
				Supplier<? extends Collection<?>> supplier = SupplierFactory.newInstance().newSupplier(propertyType);

				formerTestStatement = new RepetitiveStatement(formerTestStatement, new Holder(bean, property), supplier);
			}
			catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
				throw new RuntimeException(e);
			}
		}
		return formerTestStatement;
	}
}
